package com.koicarp.university.graduate.service.service.graduateInfoManage;

import com.koicarp.university.graduate.service.dto.bigView.BayesSampleDto;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * @auther liutao
 * @Date 2020-11-20 16:38:37
 * bayes朴素贝叶斯算法加上拉普拉斯修正解决0值问题
 */
@Slf4j
public class Bayes2 {

    private static List<BayesSampleDto> list = new ArrayList<>();
    private static Vector<BayesSampleDto> catagory_employment = new Vector<>();//存储就业的所有数据
    private static Vector<BayesSampleDto> catagory_disEmployment = new Vector<>();//存储未就业的所有数据
    private static double p_e = 0.0;
    private static double p_dis_e = 0.0;

    public static void init(List<BayesSampleDto> newList){
        list = newList;
        pretreatment(list);
        p_e = (double) (catagory_employment.size()+1) / (double) (list.size()+2);//表示概率p（R） 
        p_dis_e = (double) (catagory_disEmployment.size()+1) / (double) (list.size()+2);//表示概率p（B）
    }

    public static void pretreatment(List<BayesSampleDto> list) {   //数据预处理
        int i=0;
        while (i < list.size()){
            switch (list.get(i).getIfEmployment()){
                case 1:{
                    catagory_employment.add(list.get(i));
                    break;
                }
                case 0:{
                    catagory_disEmployment.add(list.get(i));
                    break;
                }
            }
            i++;
        }
    }

    public static double bayes(BayesSampleDto bayesSampleDto, Vector<BayesSampleDto> catagory) {
        double[] ai_y = new double[5];
        int[] sum_ai = new int[5];
        for (int j = 0; j < catagory.size(); j++) {
            if (bayesSampleDto.getIfCadre().equals(catagory.get(j).getIfCadre()))
                sum_ai[0]++;
            if (bayesSampleDto.getEnglishLevel().equals(catagory.get(j).getEnglishLevel()))
                sum_ai[1]++;
            if (bayesSampleDto.getComputerLevel().equals(catagory.get(j).getComputerLevel()))
                sum_ai[2]++;
            if (bayesSampleDto.getScholarshipNum().equals(catagory.get(j).getScholarshipNum()))
                sum_ai[3]++;
            if (bayesSampleDto.getSpecialityId().equals(catagory.get(j).getSpecialityId()))
                sum_ai[4]++;
        }
        for (int i = 0; i < 5; i++) {
            ai_y[i] = (double) (sum_ai[i]+1) / (double) (catagory.size()+2);
        }
        return ai_y[0] * ai_y[1] * ai_y[2] * ai_y[3]*ai_y[4];
    }

    /**
     * 输入一组数据判断是否能就业
     * @param bayesSampleDto 毕业生状态数据dto
     * @return true 为能够就业，false为预测不能就业
     */
    public static boolean employment(BayesSampleDto bayesSampleDto){
        double x_in_e = bayes(bayesSampleDto, catagory_employment) * p_e;
        double x_in_dis_e = bayes(bayesSampleDto, catagory_disEmployment) * p_dis_e;

        if (x_in_e == Math.max(x_in_e, x_in_dis_e)) {
            return true;
        } else if (x_in_dis_e==Math.max(x_in_e, x_in_dis_e)) {
            return false;
        }else{
            log.error("朴素贝叶斯算法错误，请查找原因");
            return false;
        }
    }
}
